iOS开发 - 在一个工程中开发多个APP

一般情况下,我们是一个 App 应用对应一个Xcode Project,但是如果你需要同时开发多个产品,而这些产品 90% 的数据结构以及交互方式都一样,呈现在用户面前的这两个产品,最大的不一样就是UI元素以及某些配色时,如果这个时候还是一个 App 一个Xcode Project,普遍的做法是:

你会先开发完成一个产品,然后在复制到其他的产品中,非常的麻烦而且效率很低,你需要一个一个文件去比对。如果你使用模块的方式,开发完一个模块,然后再利用Pod的方式导入到其他产品中,虽然这样可行,但是涉及到产品的迭代开发以及产品的随时会变的交互,模块的细化分很难实现。

如果你也面临这样的问题,不放考虑一下下面讲的一个工程来开发多个App

创建新的Target

如果现在你已经有个一个产品叫ProjectOfApps,如下图所示:

http://oboehz2ag.bkt.clouddn.com/QQ20161010-0

这时你想添加一个叫ProjectOfApps_B的产品,你需要做的是按如下的步奏进行创建: 选择Project -> Targets -> 右击ProjectOfApps -> 选择Duplicate,这时我们就按照ProjectOfApps复制了一个产品ProjectOfApps copy,并且你会看到多出了一个文件ProjectOfApps copy-Info.plist,如下图所示:

http://oboehz2ag.bkt.clouddn.com/QQ20161010-1

双击ProjectOfApps copy或选中回车,将 Target 名改为 ProjectOfApps_B

编辑Plist文件

当我们创建新的Target后会多出一个ProjectOfApps copy-Info.plist文件,这个plist文件就是控制ProjectOfApps_B的名称,版本等信息的文件,我们为了统一将他改为ProjectOfApps_B-Info.plist,在修改名字之前你需要在ProjectOfApps_BBuild Settings中找到ProjectOfApps copy-Info.plist一项,待会儿我们修改完这个plist文件以后,还需要在这里填入它正切的位置信息。这样程序执行时才能找到它,不然程序是不能通过编译的:

http://oboehz2ag.bkt.clouddn.com/QQ20161010-2

我们的原项目ProjectOfApps也可以这样修改,来达到命名的统一。如果有必要,我们也可以修改plist文件里面的选项以符合我们的预期,和Info.plist的使用并无不同。

判断当前编译的 Target

现在我们的工程里面同时包含了两个Target,现在工程里面的类是这两个Target公用的,如果你想在一个类里面区分是ProjectOfApps_A还是ProjectOfApps_B,根据开发语言的不同有两种方案:

Objective - C

Objective - C 需要设置Preprocessor Macros,它的定义很简单,选中一个Target,然后在Build Settings里面搜索Preprocessor Macros一项,然后在里面添加表明是ProjectOfApps_A的宏:

http://oboehz2ag.bkt.clouddn.com/QQ20161010-3

然后就可以判断当前编译的 Target 是哪一个了:

1
2
3
4
5
6
7
8
- (void)someFunction
{
#ifdef ProjectOfApps_A
NSLog(@"Build For Target ProjectOfApps_A!");
#else
NSLog(@"Build For Target ProjectOfApps_B!");
#endif
}

Swift

Swift 下的处理和 Objective - C 有所不同,需要设置Custom Flags,选中一个Target,然后在Build Settings里面搜索Custom Flags一项,然后在里面添加表明是ProjectOfApps_A的宏:

http://oboehz2ag.bkt.clouddn.com/QQ20161011-0

需要注意的是,这里要使用-D的格式。对应的代码如下:

1
2
3
4
5
6
7
8
9
func someFunction() {
#if ProjectOfApps_A
print("Build For Target ProjectOfApps_A!")
#elseif ProjectOfApps_B
print("Build For Target ProjectOfApps_B!")
#else
print("Other")
#endif
}

修改Scheme

现在的 Scheme 还是ProjectOfApps copyProjectOfApps,我们可以通过Manage Schemes将两个 Scheme 修改一下:

http://oboehz2ag.bkt.clouddn.com/QQ20161011-1

资源文件和类文件

如果需要为不同的 Target 区别不同的资源文件和类文件,可以使用 Xcode 的Target Membership功能,来选择该类属于哪个Target。Assets、控件也是如此。

http://oboehz2ag.bkt.clouddn.com/QQ20161011-2

参考链接

iOS中如何在一个工程创建多个App - 夏树正茂

#ifdef replacement in swift language - stackoverflow

Demo下载请点击这里